//! Tests for statement parsing

#[cfg(test)]
mod tests {
    use super::super::*;
    use crate::ast::expr::Expression;
    use crate::ast::stmt::Statement;
    use crate::parser::stmt_parser::other_stmts;

    #[test]
    fn test_parse_variable_declaration() {
        let source = "var x int = 42;".to_string();
        let mut parser = Parser::new(source, None);
        parser.advance().unwrap();

        let stmt = parse_statement(&mut parser).unwrap();
        assert!(matches!(stmt, Some(Statement::VariableDecl(_))));
    }

    #[test]
    fn test_parse_return_statement() {
        let source = "return 42;".to_string();
        let mut parser = Parser::new(source, None);
        parser.advance().unwrap();

        let stmt = parse_statement(&mut parser).unwrap();
        assert!(matches!(stmt, Some(Statement::Return(_))));
    }

    #[test]
    fn test_parse_if_statement() {
        let source = "if x > 0 { return 1; } else { return 0; }".to_string();
        let mut parser = Parser::new(source, None);
        parser.advance().unwrap();

        let stmt = parse_statement(&mut parser).unwrap();
        assert!(matches!(stmt, Some(Statement::If(_))));
    }

    #[test]
    fn test_parse_if_var_statement() {
        let source = "if var Some(value) = maybe { println(value); } else { println(0); }".to_string();
        let mut parser = Parser::new(source, None);
        parser.advance().unwrap();

        let stmt = parse_statement(&mut parser).unwrap();
        match stmt {
            Some(Statement::Block(block)) => {
                assert_eq!(block.statements.len(), 2);
                assert!(matches!(block.statements[0], Statement::VariableDecl(_)));
                match &block.statements[1] {
                    Statement::If(if_stmt) => {
                        if let Statement::Block(then_block) = &*if_stmt.then_branch {
                            assert!(!then_block.statements.is_empty());
                        } else {
                            panic!("then branch should be a block");
                        }
                    }
                    other => panic!("expected inner if statement, got {:?}", other),
                }
            }
            other => panic!("expected block statement, got {:?}", other),
        }
    }

    #[test]
    fn test_parse_for_statement() {
        let source = "for var i int in [1, 2, 3] { print(i); }".to_string();
        let mut parser = Parser::new(source, None);
        parser.advance().unwrap();

        let stmt = parse_statement(&mut parser).unwrap();
        assert!(matches!(stmt, Some(Statement::For(_))));
    }

    #[test]
    fn test_parse_defer_statement() {
        let source = "defer println(\"hello\");".to_string();
        let mut parser = Parser::new(source, None);
        parser.advance().unwrap();

        let stmt = other_stmts::parse_defer_statement(&mut parser).unwrap();
        assert!(matches!(stmt.expr, Expression::Call(_)));
    }

    #[test]
    fn test_parse_defer_statement_no_semicolon() {
        let source = "defer println(\"hello\")".to_string();
        let mut parser = Parser::new(source, None);
        parser.advance().unwrap();

        let stmt = other_stmts::parse_defer_statement(&mut parser).unwrap();
        assert!(matches!(stmt.expr, Expression::Call(_)));
    }

    #[test]
    fn test_parse_defer_statement_with_literal() {
        let source = "defer 42;".to_string();
        let mut parser = Parser::new(source, None);
        parser.advance().unwrap();

        let stmt = other_stmts::parse_defer_statement(&mut parser).unwrap();
        assert!(matches!(stmt.expr, Expression::Literal(_)));
    }
}
